﻿@using Xunit;
@inherits TestContext
@code
{
    public FluentPullToRefreshTests()
    {
        this.JSInterop.Mode = JSRuntimeMode.Loose;
        Services.AddSingleton(LibraryConfiguration.ForUnitTests);
    }

    // write some unit tests here
    [Fact]
    public void FluentPullToRefresh_Default()
    {
        // Arrange && Act
        var cut = Render(@<FluentPullToRefresh>Content that can be refreshed</FluentPullToRefresh>);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentPullToRefresh_DirectionDown()
    {
        // Arrange && Act
        var cut = Render(@<FluentPullToRefresh Direction="@PullDirection.Down">Content that can be refreshed</FluentPullToRefresh>);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentPullToRefresh_DirectionUp()
    {
        // Arrange && Act
        var cut = Render(@<FluentPullToRefresh Direction="@PullDirection.Up">Content that can be refreshed</FluentPullToRefresh>);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentPullToRefresh_Disabled()
    {
        // Arrange && Act
        var cut = Render(@<FluentPullToRefresh Disabled="true">Content that can be refreshed</FluentPullToRefresh>);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentPullToRefresh_DoNotShowStaticTip()
    {
        // Arrange && Act
        var cut = Render(@<FluentPullToRefresh ShowStaticTip="false">Content that can be refreshed</FluentPullToRefresh>);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentPullToRefresh_LoadingTemplate()
    {
        // Arrange && Act
        var cut = Render(@<FluentPullToRefresh>
            <PullingTemplate>Pull to refresh...</PullingTemplate>
            <ChildContent>Content that can be refreshed</ChildContent>
        </FluentPullToRefresh>);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentPullToRefresh_PullingTemplate()
    {
        // Arrange && Act
        var cut = Render(@<FluentPullToRefresh>
            <PullingTemplate>Pull to refresh...</PullingTemplate>
            <ChildContent>Content that can be refreshed</ChildContent>
        </FluentPullToRefresh>);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentPullToRefresh_ReleaseTemplate()
    {
        // Arrange && Act
        var cut = Render(@<FluentPullToRefresh>
            <ReleaseTemplate>Release to refresh...</ReleaseTemplate>
            <ChildContent>Content that can be refreshed</ChildContent>
        </FluentPullToRefresh>);

        // Assert
        cut.Verify();
    }

    [Fact]

    public void FluentPullToRefresh_CompletedTemplate()
    {
        // Arrange && Act
        var cut = Render(@<FluentPullToRefresh>
            <CompletedTemplate>Refresh completed</CompletedTemplate>
            <ChildContent>Content that can be refreshed</ChildContent>
        </FluentPullToRefresh>);

        // Assert
        cut.Verify();
    }


    [Fact]
    public void FluentPullToRefresh_NoDateTemplate()
    {
        // Arrange && Act
        var cut = Render(@<FluentPullToRefresh>
            <NoDataTemplate>No more data</NoDataTemplate>
            <ChildContent>Content that can be refreshed</ChildContent>
        </FluentPullToRefresh>
    );

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentPullToRefresh_ChildContent()
    {
        // Arrange && Act
        var cut = Render(@<FluentPullToRefresh>Content that can be refreshed</FluentPullToRefresh>);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentPullToRefresh_OnRefreshAsync()
    {
        // Arrange && Act
        Func<Task<bool>> OnRefreshAsync = () => { return Task<bool>.FromResult(true); };

        var cut = Render(@<FluentPullToRefresh OnRefreshAsync="OnRefreshAsync">Content that can be refreshed</FluentPullToRefresh>);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentPullToRefresh_EmulateTouch()
    {
        // Arrange && Act
        var cut = Render(@<FluentPullToRefresh EmulateTouch="false">Content that can be refreshed</FluentPullToRefresh>);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentPullToRefresh_StaticTipOnTouchMoveAsync()
    {
        // Arrange && Act
        var cut = Render(@<FluentPullToRefresh ShowStaticTip="false">
            <PullingTemplate>Pull to refresh...</PullingTemplate>
            <ChildContent>Content that can be refreshed</ChildContent>
        </FluentPullToRefresh>);

        var div = cut.Find("div.fluent-pull-container");
        var touchArgsStart = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 0 } } };
        div.TriggerEvent("ontouchstart", touchArgsStart);

        var touchArgsMove = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 32 } } };
        div.TriggerEvent("ontouchmove", touchArgsMove);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentPullToRefresh_ReleaseTemplateOnTouchMoveAsync()
    {
        // Arrange && Act
        var cut = Render(@<FluentPullToRefresh Direction="@PullDirection.Down">
            <ChildContent>Content that can be refreshed</ChildContent>
        </FluentPullToRefresh>);

        var div = cut.Find("div.fluent-pull-container");
        var touchArgsStart = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 0 } } };
        div.TriggerEvent("ontouchstart", touchArgsStart);

        var touchArgsMove = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 100 } } };
        div.TriggerEvent("ontouchmove", touchArgsMove);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentPullToRefresh_CompletedTemplateOnTouchMoveAsync()
    {
        // Arrange && Act
        var cut = Render(@<FluentPullToRefresh Direction="@PullDirection.Down">
        <ChildContent>Content that can be refreshed</ChildContent>
    </FluentPullToRefresh>);

        var div = cut.Find("div.fluent-pull-container");
        var touchArgsStart = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 0 } } };
        div.TriggerEvent("ontouchstart", touchArgsStart);

        var touchArgsMove = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 100 } } };
        div.TriggerEvent("ontouchmove", touchArgsMove);

        var touchArgsEnd = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 100 } } };
        div.TriggerEvent("ontouchend", touchArgsEnd);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentPullToRefresh_ReleaseTemplateOnTouchMoveAsyncUp()
    {
        // Arrange && Act
        var cut = Render(@<FluentPullToRefresh Direction="@PullDirection.Up">
        <PullingTemplate>Pull to refresh...</PullingTemplate>
        <ReleaseTemplate>Release to refresh...</ReleaseTemplate>
        <ChildContent>Content that can be refreshed</ChildContent>
    </FluentPullToRefresh>);

        var div = cut.Find("div.fluent-pull-container");
        var touchArgsStart = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 150 } } };
        div.TriggerEvent("ontouchstart", touchArgsStart);

        var touchArgsMove = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 0 } } };
        div.TriggerEvent("ontouchmove", touchArgsMove);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentPullToRefresh_CompletedTemplateOnTouchMoveAsyncUp()
    {
        // Arrange && Act
        var cut = Render(@<FluentPullToRefresh Direction="@PullDirection.Down">
        <PullingTemplate>Pull to refresh...</PullingTemplate>
        <ReleaseTemplate>Release to refresh...</ReleaseTemplate>
        <CompletedTemplate>Update completed...</CompletedTemplate>
        <ChildContent>Content that can be refreshed</ChildContent>
    </FluentPullToRefresh>);

        var div = cut.Find("div.fluent-pull-container");
        var touchArgsStart = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 150 } } };
        div.TriggerEvent("ontouchstart", touchArgsStart);

        var touchArgsMove = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 0 } } };
        div.TriggerEvent("ontouchmove", touchArgsMove);

        var touchArgsEnd = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 0 } } };
        div.TriggerEvent("ontouchend", touchArgsEnd);

        // Assert
        cut.Verify();
    }


    [Fact]
    public void FluentPullToRefresh_OnTouchMoveAsyncMoreOnRefreshAsyncTrue()
    {
        // Arrange && Act
        Func<Task<bool>> OnRefreshAsync = () => { return Task<bool>.FromResult(true); };

        var cut = Render(@<FluentPullToRefresh Direction="@PullDirection.Down" OnRefreshAsync="OnRefreshAsync" StatusUpdateMessageTimeout="0">
        <PullingTemplate>Pull to refresh...</PullingTemplate>
        <ReleaseTemplate>Release to refresh...</ReleaseTemplate>
        <NoDataTemplate>No more data...</NoDataTemplate>
        <CompletedTemplate>Update completed...</CompletedTemplate>
        <ChildContent>Content that can be refreshed</ChildContent>
    </FluentPullToRefresh>);

        var div = cut.Find("div.fluent-pull-container");
        var touchArgsStart = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 0 } } };
        div.TriggerEvent("ontouchstart", touchArgsStart);

        var touchArgsMove = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 100 } } };
        div.TriggerEvent("ontouchmove", touchArgsMove);

        var touchArgsEnd = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 0 } } };
        div.TriggerEvent("ontouchend", touchArgsEnd);

        // Assert
        cut.Verify();
    }

    [Fact]
    public void FluentPullToRefresh_OnTouchMoveAsyncMoreOnRefreshAsyncFalse()
    {
        // Arrange && Act
        Func<Task<bool>> OnRefreshAsync = () => { return Task<bool>.FromResult(false); };

        var cut = Render(@<FluentPullToRefresh Direction="@PullDirection.Down" OnRefreshAsync="OnRefreshAsync">
        <ChildContent>Content that can be refreshed</ChildContent>
    </FluentPullToRefresh>);

        var div = cut.Find("div.fluent-pull-container");
        var touchArgsStart = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 0 } } };
        div.TriggerEvent("ontouchstart", touchArgsStart);

        var touchArgsMove = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 100 } } };
        div.TriggerEvent("ontouchmove", touchArgsMove);

        var touchArgsEnd = new TouchEventArgs() { TargetTouches = new[] { new TouchPoint() { ClientX = 10, ClientY = 0 } } };
        div.TriggerEvent("ontouchend", touchArgsEnd);

        // Assert
        cut.Verify();
    }
}
